package com.ddm.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ddm.dto.page.PageQueryDTO;
import com.ddm.entity.*;
import com.ddm.exception.BaseException;
import com.ddm.mapper.*;
import com.ddm.result.PageResult;
import com.ddm.service.CommonService;
import com.ddm.service.StandardService;
import com.ddm.vo.StandardDetailVO;
import com.ddm.vo.page.MenuPageQueryVO;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

import static com.ddm.constant.LevelConstant.LAST_INDEX;

/**
 * <p>
 * 标准表 服务实现类
 * </p>
 *
 * @author 丁丁猫
 * @since 2025-01-13
 */
@Service
public class StandardServiceImpl extends ServiceImpl<StandardMapper, Standard> implements StandardService {

    @Autowired
    private CommonService commonService;

    @Autowired
    private TermMapper termMapper;

    @Autowired
    private StandardMapper standardMapper;

    @Autowired
    private Level1Mapper level1Mapper;

    @Autowired
    private Level2Mapper level2Mapper;

    @Autowired
    private Level3Mapper level3Mapper;

    @Autowired
    private Level4Mapper level4Mapper;

    @Autowired
    private FileMapper fileMapper;



    /**
     * 根据关键词分页查询标准文档
     *
     * @param pageQueryDTO
     * @return
     */
    @Override
    public PageResult pageQueryByKeyword(PageQueryDTO pageQueryDTO) {
        IPage<Standard> page = new Page(pageQueryDTO.getPage(), pageQueryDTO.getPageSize());

        LambdaQueryWrapper<Standard> lqw = new LambdaQueryWrapper();
        lqw.like(null != pageQueryDTO.getKey(), Standard::getStandardName, pageQueryDTO.getKey())
                .like(StringUtils.isNotEmpty(pageQueryDTO.getLevelType()), Standard::getLevel, pageQueryDTO.getLevelType())
                .orderByDesc(Standard::getPublicationDate);
        standardMapper.selectPage(page, lqw);
        long total = page.getTotal();
        List<Standard> records = page.getRecords();
        //设置数据
        PageResult pageResult = new PageResult(total, records);
        return pageResult;
    }

    /**
     * 根据ID查询标准文档详情
     * @param id
     * @return
     */
    @Override
    public StandardDetailVO getStandardDetailById(Long id) {
        StandardDetailVO standardDetailVO = new StandardDetailVO();
        standardDetailVO.setStandard(standardMapper.selectById(id));
        Long standardId = standardDetailVO.getStandard().getId();
        standardDetailVO.setTerms(termMapper.selectList(new LambdaQueryWrapper<Term>().eq(Term::getStandardId, standardId)));
        standardDetailVO.setLevel1(getStandardLevel(standardId));
        File file = fileMapper.selectOne(new LambdaQueryWrapper<File>().eq(File::getStandardId, standardId));
        if (file != null) {
            standardDetailVO.setFileName(file.getFileName());
            standardDetailVO.setFile(file.getFile());
            standardDetailVO.setFileId(file.getId());
        }
        return standardDetailVO;
    }



    /**
     * 分页查询菜单项
     *
     * @return
     */
    @Override
    public PageResult pageQueryMenu() {
        List<MenuPageQueryVO> menus = new ArrayList<>();
        //根据Standard的publicationDate降序排序
        LambdaQueryWrapper<Standard> lqwStandard = new LambdaQueryWrapper();
        lqwStandard.orderByDesc(Standard::getPublicationDate);
        //根据Term的id升序
        LambdaQueryWrapper<Term> lqwTerm = new LambdaQueryWrapper();
        lqwTerm.orderByAsc(Term::getId);
        //查询所有标准文档
        lqwStandard.orderByDesc(Standard::getPublicationDate);
        List<Standard> standards = standardMapper.selectList(lqwStandard);
        //插入标准文件到菜单项
        for (Standard standard : standards) {
            MenuPageQueryVO menu = new MenuPageQueryVO();
            //设置标准文档属性
            menu.setId(standard.getId());
            menu.setStandardName(standard.getStandardName());
            menu.setPublicationDate(standard.getPublicationDate());
            //查询所有术语[StandardId和标准文档id相同]
            lqwTerm.eq(Term::getStandardId, standard.getId());
            List<Term> terms = termMapper.selectList(lqwTerm);
            //menu封装所有术语，写出完整代码
            menu.setTerms(terms);
            //获取所有level1
            List<Level1> level1List = getStandardLevel(standard.getId());
            menu.setLevel1(level1List);
            menu.setType(standard.getLevel());
            //添加到menus中
            menus.add(menu);
        }
        //设置数据
        PageResult pageResult = new PageResult(menus.size(), menus);
        return pageResult;
    }

    /**
     * 根据标准ID查询标准文档的所有level
     *
     * @param standardId
     * @return
     */
    @Override
    public List<Level1> getStandardLevel(Long standardId) {
        // 查询并按 numId 排序的 Level1 节点
        LambdaQueryWrapper<Level1> lqwLevel1 = new LambdaQueryWrapper<>();
        lqwLevel1.eq(Level1::getStandardId, standardId)
                .orderByAsc(Level1::getNumId);
        List<Level1> level1List = level1Mapper.selectList(lqwLevel1);
        level1List.sort(Comparator.comparing(level1 -> Integer.parseInt(commonService.extractNumId(level1.getNumId(),LAST_INDEX))));

        // 查询并按 numId 排序的 Level2 节点
        LambdaQueryWrapper<Level2> lqwLevel2 = new LambdaQueryWrapper<>();
        lqwLevel2.eq(Level2::getStandardId, standardId)
                .orderByAsc(Level2::getNumId);
        List<Level2> level2List = level2Mapper.selectList(lqwLevel2);
        level2List.sort(Comparator.comparing(level2 -> Integer.parseInt(commonService.extractNumId(level2.getNumId(),LAST_INDEX))));

        // 查询并按 numId 排序的 Level3 节点
        LambdaQueryWrapper<Level3> lqwLevel3 = new LambdaQueryWrapper<>();
        lqwLevel3.eq(Level3::getStandardId, standardId)
                .orderByAsc(Level3::getNumId);
        List<Level3> level3List = level3Mapper.selectList(lqwLevel3);
        level3List.sort(Comparator.comparing(level3 -> Integer.parseInt(commonService.extractNumId(level3.getNumId(),LAST_INDEX))));

        // 查询并按 numId 排序的 Level4 节点
        LambdaQueryWrapper<Level4> lqwLevel4 = new LambdaQueryWrapper<>();
        lqwLevel4.eq(Level4::getStandardId, standardId)
                .orderByAsc(Level4::getNumId);
        List<Level4> level4List = level4Mapper.selectList(lqwLevel4);
        level4List.sort(Comparator.comparing(level4 -> Integer.parseInt(commonService.extractNumId(level4.getNumId(),LAST_INDEX))));

        // 构建树形结构，逐层关联子节点
        for (Level1 level1 : level1List) {
            if (level1.getIfNextLevel() == 0) {
                continue;
            }
            // 关联 Level2
            String parentPrefix1 = level1.getNumId() + ".";
            List<Level2> childLevel2 = level2List.stream()
                    .filter(level2 -> level2.getNumId().startsWith(parentPrefix1))
                    .collect(Collectors.toList());
            level1.setLevel2(childLevel2);;
            for (Level2 level2 : childLevel2) {
                if (level2.getIfNextLevel() == 0) {
                    continue;
                }
                // 关联 Level3
                String parentPrefix2 = level2.getNumId() + ".";
                List<Level3> childLevel3 = level3List.stream()
                        .filter(level3 -> level3.getNumId().startsWith(parentPrefix2))
                        .collect(Collectors.toList());
                level2.setLevel3(childLevel3);
                for (Level3 level3 : childLevel3) {
                    if (level3.getIfNextLevel() == 0) {
                        continue;
                    }
                    // 关联 Level4
                    String parentPrefix3 = level3.getNumId() + ".";
                    List<Level4> childLevel4 = level4List.stream()
                            .filter(level4 -> level4.getNumId().startsWith(parentPrefix3))
                            .collect(Collectors.toList());
                    level3.setLevel4(childLevel4);
                }
            }
        }
        return level1List;
    }


}

